
#include <BFont>
#include <BPainter>
#include <BScrollBar>
#include "member_BGraphicWidget.h"
#include "member_BGraphicItem.h"

using namespace BWE;

member_BGraphicWidget::member_BGraphicWidget(BGraphicWidget* graphic)
{
	boss = graphic;
	selectMode = Select_Multiple | Select_Continuous;
	dirty = true;
	pressed = false;
	hoveredItem = 0;
}
member_BGraphicWidget::~member_BGraphicWidget()
{

}

bool member_BGraphicWidget::freshContents()
{
	contentRect = boss->area();
	contentRect.reset();
	for (int i = 0; i < items.size(); i++)
	{
		BGraphicItem* item = items[i];
		if (i == 0)
			contentRect = item->absoluteRect();
		else
			contentRect.expand(item->absoluteRect());
	}
	return true;
}
void member_BGraphicWidget::freshItem(BGraphicItem* item, const BEvent& event)
{
	if (!item_member(item)->visible)
		return;

	if (item_member(item)->refresh)
	{
		item_member(item)->refresh = false;
		item_member(item)->event(event);
		item_member(item)->area = item_member(item)->rect;
	}

	const BPointf& pos = item_member(item)->pos;
	for (int i = 0; i < item->childCount(); i++)
	{
		BGraphicItem* child = item->child(i);
		if (item_member(child)->visible)
		{
			freshItem(child, event);
			item_member(item)->area.expand(child->area() + pos);
		}
	}

}
void member_BGraphicWidget::paintItem(BGraphicItem* item, BPainter& painter)
{
	if (!item_member(item)->visible)
		return;

	painter.pushMatrix();
	painter.translate(item_member(item)->pos);
	painter.rotate(item_member(item)->rotate);
	item_member(item)->paint(painter);

	BArray<BGraphicItemHolder>& children = item_member(item)->children;
	for (int i = 0; i < children.size(); i++)
	{
		BGraphicItem* child = children[i];
		if (hoveredItem == child)
		{
			item_member(child)->hovered = true;
			if (pressed)
				item_member(child)->pressed = true;
		}
		else
		{
			item_member(child)->hovered = false;
			item_member(child)->pressed = false;
		}
		paintItem(child, painter);
	}

	painter.popMatrix();
}
BGraphicItem* member_BGraphicWidget::locateItem(BPointf point, BGraphicItem* item)
{
	BPointf pos = item_member(item)->pos;
	BArray<BGraphicItemHolder>& children = item_member(item)->children;
	for (int i = children.size() - 1; i >= 0; i--)
	{
		BGraphicItem* child = children[i];
		BGraphicItem* result = locateItem(point - pos, child);
		if (result)
			return result;
	}
	if (item->catchPoint(point - pos))
	{
		return item;
	}
	return 0;
}
void member_BGraphicWidget::collectVisualItems(BGraphicItem* item, const BPoint& offset, const BRect& crect)
{
	BRectf rect = item_member(item)->rect + offset;
	if (crect.intersect(rect))
	{
		visualItems.append(item);
	}
	for (int i = 0; i < item->childCount(); i++)
	{
		BGraphicItem* child = item->child(i);
		if (!item_member(child)->visible)
			continue;
		collectVisualItems(child, offset, crect);
	}
}
bool member_BGraphicWidget::collectPrevItems(BGraphicItem* item, BGraphicItem* lastItem, BGraphicItemList& collectedItems)
{
	while (item)
	{
		collectedItems.append(item);
		if (item == lastItem)
			return true;
		for (int i = 0; i < item->childCount(); i++)
		{
			BGraphicItem* child = item->child(i);
			if (collectPrevItems(child, lastItem, collectedItems))
				return true;
		}
		item = item->prev();
	}
	return false;
}
bool member_BGraphicWidget::collectNextItems(BGraphicItem* item, BGraphicItem* lastItem, BGraphicItemList& collectedItems)
{
	while (item)
	{
		collectedItems.append(item);
		if (item == lastItem)
			return true;
		for (int i = 0; i < item->childCount(); i++)
		{
			BGraphicItem* child = item->child(i);
			if (collectNextItems(child, lastItem, collectedItems))
				return true;
		}
		item = item->next();
	}
	return false;
}
